#include "udpServer.hpp"
#include "onlineUser.hpp"
#include <memory>
#include <unordered_map>
#include <fstream>

//unordered_map<string, string> dict;

void Usage(string proc)
{
    cout << "\nUsage:\n\t" << proc << " local_port\n" << endl;
}

void sepString(string& s, string& k, string& v, string sep)
{
    size_t pos = s.find(sep);
    k = s.substr(0, pos);
    v = s.substr(pos + 1);
}

// void initDict()
// {
//     ifstream in("./dict.txt", ios_base::binary);
//     if (!in.is_open())
//     {
//         cout << "initDict failed" << endl;
//         exit(4);
//     }
//     string line;
//     while (getline(in, line))
//     {
//         string key, value;
//         sepString(line, key, value, ":");
//         dict.insert(make_pair(key, value));
//     }
// }

//demo1 字典应用
//以回调的形式处理客户端发来的消息 实现网络通信与业务逻辑的解耦
// void handlerMessage(string& message, string& ip, uint16_t port, int sockfd)
// {
//     //处理信息
//     string response_message;
//     auto iter = dict.find(message);
//     if (iter == dict.end())
//         response_message = "unknown";
//     else
//         response_message = iter->second;
    
//     //返回处理结果
//     struct sockaddr_in client;
//     client.sin_family = AF_INET;
//     client.sin_port = htons(port);
//     client.sin_addr.s_addr = inet_addr(ip.c_str());
//     sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr*)&client, sizeof client);
// }

//demo2 myshell
// void execCommand(string& cmd, string& ip, uint16_t port, int sockfd)
// {
//     if(cmd.find("rm") != string::npos || cmd.find("mv") != string::npos || cmd.find("rmdir") != string::npos)
//     {
//         cerr << ip << ":" << port << " 正在做一个非法的操作: " << cmd << endl;
//         return;
//     }
//     //必要时可以考虑创建子进程或进程程序替换执行命令
//     string response_message;
//     FILE* fp = popen(cmd.c_str(), "r");//创建管道文件和子进程 用子进程执行shell命令 将执行结果导入管道 管道内容只读或只写
//     if (fp == nullptr)
//     {
//         cout << cmd + " exec failed" << endl;
//         return;
//     }
//     char line[1024];
//     while (fgets(line, sizeof line, fp))
//         response_message += line;
//     pclose(fp);

//     //将处理消息返回给客户端
//     struct sockaddr_in client;
//     client.sin_family = AF_INET;
//     client.sin_port = htons(port);
//     client.sin_addr.s_addr = inet_addr(ip.c_str());//将点分十进制字符串转为网络字节序
//     //发什么 发多少 发给谁
//     sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr*)&client, sizeof client);
// }

//demo3 聊天室
OnlineUser onlineuser;

void routineMessage(string& message, string& ip, uint16_t port, int sockfd)
{
    if (message == "online")
        onlineuser.addUser(ip, port);
    if (message == "offline")
        onlineuser.delUser(ip, port);
    if (onlineuser.isOnline(ip, port))
    {
        onlineuser.broadcastMessage(ip, port, message, sockfd);
    }
    else//用户未上线
    {
        struct sockaddr_in client;
        client.sin_family = AF_INET;
        client.sin_port = htons(port);
        client.sin_addr.s_addr = inet_addr(ip.c_str());
        string response_message = "请先上线 运行online";
        sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr*)&client, sizeof client);
    }
}


int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(3);
    }
    //initDict();
    uint16_t port = atoi(argv[1]);
    unique_ptr<udpServer> usvr(new udpServer(routineMessage, port));
    usvr->initServer();
    usvr->start();
    return 0;
}